# = Class ASTListComma
# Inherits from ASTExpression. Represents the implementation of an AST especifically designed
# for comma separated lists of expressions
# == Attributes inherited from ASTExpression
# node, children
# == Methods inherited from ASTExpression
# check(), run(), to_s_children(im)
class ASTListComma < AST
  # Type of each element in the list
  attr_reader :type
  # Value of the list after eval is performed
  attr_reader :value

  # Constructor of the class
  # === Parameters
  # * head: List of comma separated elements to which elem is going to be added
  # * elem: Element to be added to the list
  def initialize elem, head
    @children = head
    @children.push elem
  end

  # Method to evaluate the list
  # === Parameters
  # * parent_sym_table: Symbol table passed by the parent AST
  # * func_table: Function symbol table passed by the parent AST
  # === Return value
  # nil if executed with success or an error message
  def eval parent_sym_table, func_table
    if !@children[0].kind_of?ASTExpression
      return "Error interno: Tratando de evaluar una lista que no es de expresiones (#{error_location})"
    end
    @value = []
    for elem in @children
      msg = elem.eval parent_sym_table, func_table
      if nil != msg
        return msg
      end
      @value.push(elem.value)
    end
    nil
  end

  
  # Method to check the static correctitude of the list
  # === Parameters
  # * parent_sym_table: Symbol table passed by the parent AST
  # * func_table: Function symbol table passed by the pare
  # * func_type: Type of valid return value
  # === Return value
  # nil if executed with success or an error message
  def check parent_sym_table, func_table, func_type
    
    @type = []
    ast = (@children[0].kind_of?ASTFunc) ? ASTFunc :
          (@children[0].kind_of?ASTVar) ? ASTVar :
          (@children[0].kind_of?ASTExpression) ? ASTExpression : nil

    for elem in @children
      if !elem.kind_of?ast
        return "Error interno: lista de #{ast.name} contiene #{elem.class.name} (#{elem.error_location})"
      end
      msg = elem.check parent_sym_table, func_table, func_type
      if nil != msg
        return msg
      end
      @type.push elem.type
    end
    nil
  end

  # Returns the closest wrong token to the place were an error is generated
  def error_tk
    for e in @children
      tk = e.error_tk
      if nil != tk
        return tk
      end
    end
    nil
  end
  
  # Creates a 'String' representation of the AST with 'i' identation spaces
  # === Parameters
  # * i: Identation with which the AST should be printed with
  def to_s(i)
    im = i + @@c
    "(Lista separada por comas#{to_s_children(im)}\n#{i})"
  end
end